การจัดการ laravel.log ด้วย CloudWatch Logs บน Elastic Beanstalk
ครั้งนี้ผมจะมาแนะนำเกี่ยวกับ การจัดการ laravel.log ด้วย CloudWatch Logs บน Elastic Beanstalk
สิ่งที่ต้องมี
ทำการ Deploy Laravel ด้วย Elastic Beanstalk และเชื่อมต่อกับ RDS ตามบทความด้านล่างนี้ครับ
เมื่อทำวิธีการตามลิงก์ในหัวข้อ สิ่งที่ต้องมี เสร็จแล้ว ให้เริ่มทำขั้นตอนถัดไปได้เลยครับ
การตั้งค่า CloudWatch Log และ Deploy Laravel ใน Elastic Beanstalk
ทำการสร้างไฟล์และโฟลเดอร์ที่จะใช้ตั้งค่า CloudWatch ในขณะที่ระบบ Deploy Laravel ใน Elastic Beanstalk ดังนี้
สร้าง: [.ebextensions/03_cloudwatchlog.config
] และ Copy Code นี้วางที่ไฟล์03_cloudwatchlog.config
files: "/home/ec2-user/cloudwatch_log_setup.sh": mode: "000755" owner: root group: root content: | #!/bin/bash # export $(cat /opt/elasticbeanstalk/deployment/env | grep -v ^# | xargs); export INSTANCE_ID=`cat /var/lib/cloud/data/instance-id` aws logs create-log-group --log-group-name "/${APP_NAME}/${APP_ENV}/laravel_log" --region ap-southeast-1 aws logs put-retention-policy --log-group-name "/${APP_NAME}/${APP_ENV}/laravel_log" --retention-in-days 30 --region ap-southeast-1 aws logs create-log-stream --log-group-name "/${APP_NAME}/${APP_ENV}/laravel_log" --log-stream-name ${INSTANCE_ID} --region ap-southeast-1 echo -n "" >> /etc/awslogs/awslogs.conf echo "[laravel_log]" >> /etc/awslogs/awslogs.conf echo "log_group_name=/${APP_NAME}/${APP_ENV}/laravel_log" >> /etc/awslogs/awslogs.conf echo "log_stream_name=${INSTANCE_ID}" >> /etc/awslogs/awslogs.conf echo "file=/var/app/current/storage/logs/laravel*.log" >> /etc/awslogs/awslogs.conf echo "datetime_format=%Y-%m-%d %H:%M:%S" >> /etc/awslogs/awslogs.conf echo "buffer_duration=5000" >> /etc/awslogs/awslogs.conf echo "initial_position=start_of_file" >> /etc/awslogs/awslogs.conf echo "time_zone=LOCAL" >> /etc/awslogs/awslogs.conf echo "" >> /etc/awslogs/awslogs.conf container_commands: "01_awslogs_install": command: | echo `date`." 01_awslogs_install" >> /var/log/ebextensions_test.log yum install awslogs -y /home/ec2-user/cloudwatch_log_setup.sh echo -n "" > /etc/awslogs/awscli.conf echo "[plugins]" >> /etc/awslogs/awscli.conf echo "cwlogs = cwlogs" >> /etc/awslogs/awscli.conf echo "[default]" >> /etc/awslogs/awscli.conf echo "region = ap-southeast-1" >> /etc/awslogs/awscli.conf sed -i -e "s/^\[\/var\/log\/messages\]/# \[\/var\/log\/messages\]/" /etc/awslogs/awslogs.conf sed -i -e "s/^datetime_format \= \%b \%d \%H\:\%M\:\%S/# datetime_format \= \%b \%d \%H\:\%M\:\%S/" /etc/awslogs/awslogs.conf sed -i -e "s/^file \= \/var\/log\/messages/# file \= \/var\/log\/messages/" /etc/awslogs/awslogs.conf sed -i -e "s/^buffer_duration \= 5000/# buffer_duration \= 5000/" /etc/awslogs/awslogs.conf sed -i -e "s/^log_stream_name \= /# log_stream_name \= /" /etc/awslogs/awslogs.conf sed -i -e "s/^initial_position \= start_of_file/# initial_position \= start_of_file/" /etc/awslogs/awslogs.conf sed -i -e "s/^log_group_name \= \/var\/log\/messages/# log_group_name \= \/var\/log\/messages/" /etc/awslogs/awslogs.conf systemctl restart awslogsd systemctl enable awslogsd
เมื่อเตรียมไฟล์การตั้งค่า CloudWatch Log เสร็จแล้ว ให้ทำการสร้างไฟล์ Zip และ Deploy ใน Elastic Beanstalk
การสร้าง Role ใน IAM
ขั้นตอนนี้ผมจะสร้าง Role เพื่อนำไปใช้กับ EC2 ที่จะสร้างใน Elastic Beanstalk ในขั้นตอนถัดไปครับ
ดูตัวอย่างที่นี่เฉพาะหัวข้อนี้: การสร้าง Role ใน IAM
ตัวอย่างการสร้าง Role ใน IAM ของบทความนี้
※Step 1: Select trusted entity
Trusted entity type: ◉AWS service
Use case
Common use cases: ◉EC2
(ข้อควรระวัง: เราจะไม่ใช้ Elastic Beanstalk ! แต่ให้ใช้ EC2)※Step 2: Add permissions
Permissions policies:CloudWatchLogsFullAccess
,AWSElasticBeanstalkWebTier
【หมายเหตุ: Permission ที่ต้องทำการอนุญาตที่นี่คือ CloudWatchLog ดังนั้นให้เพิ่ม "CloudWatchLogsFullAccess"
นอกจากนี้ Elastic Beanstalk ต้องได้รับการเพิ่ม Permission ของ "AWSElasticBeanstalkWebTier" เข้ามาด้วย】※Step 3: Name, review, and create
Role details
Role name:ec2-tinnakorn-cloudwatchlog
การตั้งค่าขณะสร้าง Environment ใน Elastic Beanstalk
ผมจะสร้าง Environment ใน Application ที่ชื่อว่าtinnakorn
ที่สร้างไว้ก่อนหน้านี้ครับ
ตอนสร้าง Environment แนะนำให้ใช้วิธีในบทความนี้ครับ และในส่วนของการตั้งค่าConfigure more options
ให้ดูตามขั้นตอนของ ตัวอย่างการสร้าง Environment ของบทความนี้ ที่ด้านล่างนี้ครับ (ถ้ามีขั้นตอนที่ซ้ำกันให้ข้ามไปได้เลยครับ)
ตัวอย่างการสร้าง Environment ของบทความนี้
※Environment information
Environment name:tinnakorn-cloudwatchlog
(ชื่ออะไรก็ได้)
Domain:tinnakorn-cloudwatchlog
(ชื่ออะไรก็ได้)※Platform
Platform:PHP
※Application code
เลือกวิธีอัปโหลดไฟล์ตามที่คุณต้องการ
** จากนี้ไปให้ดูวิธีการตั้งค่าใน [Configure more options] จากตัวอย่างและลิงก์ที่เรียงไว้ด้านล่างนี้ **เมื่อทำเสร็จในแต่ละขั้นตอนของลิงก์ด้านล่างนี้แล้ว อย่าพึ่งคลิกปุ่ม
Create environment
นะครับ เพราะว่าต้องตั้งค่าให้ครบตามที่เขียนไว้ด้านล่างนี้
- การตั้งค่าหน้า Configure more options สำหรับการใช้ ELB (ALB)
เข้าไปที่ Software ตรงหัวข้อ
Environment properties
แล้วเปลี่ยน APP_ENV และ APP_NAME ตามตัวอย่างนี้
【หมายเหตุ: เนื่องจากใช้ตัวแปรสภาพแวดล้อม (APP_ENV, APP_NAME) ในการตั้งค่า CloudWatch Logs จึงจำเป็นต้องตั้งค่าทั้ง 2 ตัวนี้ และตั้งชื่อไม่ให้เหมือนกันในแต่ละ Environment】
» APP_ENV=cloudwatchlog
» APP_NAME=tinnakorn
» เมื่อเปลี่ยนเสร็จแล้ว เลื่อนลงมาด้านล่างสุด คลิกSave
กลับมาที่หัวข้อหัวข้อ Security แล้วตั้งค่าดังนี้
Virtual machine permissions
» IAM instance profile:ec2-tinnakorn-cloudwatchlog
» คลิกSave
เมื่อตั้งค่าตามขั้นตอนข้างต้นเสร็จแล้ว ให้เลื่อนลงมาด้านล่างสุดและคลิกปุ่ม
Create environment
จากนั้นรอระบบเริ่มต้นสักครู่ครับ
ถ้าเสร็จแล้วให้คลิกลิงก์เปิดหน้าเว็บไซต์โปรเจกต์ของเราจากหน้า Environment ได้เลยครับ (ลิงก์นี้เป็นแค่ตัวอย่าง)
http://tinnakorn-cloudwatchlog.ap-southeast-1.elasticbeanstalk.com/
ตรวจสอบ CloudWatch Log
ไปที่ Service [CloudWatch > Log groups]
ทำการตรวจสอบ Log ดังนี้:
ค้นหาชื่อของเรา เช่น/tinnakorn/cloudwatchlog
แล้วคลิกเข้าไปครับ (นี่คือตัวแปรสภาพแวดล้อมที่ถูกใช้งาน ซึ่งเป็น/APP_NAME/APP_ENV
นั่นเอง)
เมื่อเข้ามาแล้วดูที่ Log streams จะเห็นว่ามี Instance ID แสดงขึ้นมา 2 ตัวตามที่กำหนดไว้ใน Elastic Beanstalk
ซึ่งเราสามารถ Copy Instance ID จากที่นี่ไปค้นหาในหน้า Instance ได้ครับ
ทีนี้ให้คลิกเข้าไปดูในแต่ละ Instance ได้เลยครับ
Instance ID ของบทความนี้:i-0d63fc42463547f0a
,i-028ffabac790e4516
จะเห็นว่าไม่มีข้อมูลแสดงใน Log events เพราะว่ายังไม่มี Error ครับ
เชื่อมต่อ Server EC2 ด้วย SSH
ดูตัวอย่างการเชื่อมต่อ Server EC2 ด้วย SSH จาก EC2 ไปยัง EC2 อื่นตามลิงก์บทความด้านล่างนี้ครับ
ทดสอบ Error Log ใน VSCode และ CloudWatch Log
เมื่อเชื่อมต่อเสร็จแล้ว รันคำสั่งด้านล่างใน Server EC2 ทั้ง 2 ตัวนี้เพื่อดูข้อมูล Error ใน awslogs.log
tail -f /var/log/awslogs.log
ตอนที่ยังไม่มี Error จะแสดงหน้าจอแบบนี้
กลับมาที่หน้าเว็บไซต์โปรเจกต์ของเรา แล้วเปิดหน้าเว็บอะไรก็ได้ที่ทำให้เกิด Error เพื่อให้บันทึก Log ไปยัง laravel.log เช่น
http://tinnakorn-cloudwatchlog.ap-southeast-1.elasticbeanstalk.com/customer/3
กลับมาที่ VSCode จะเห็นว่ามี Error แสดงขึ้นมาแล้ว ซึ่งในส่วนของ/var/app/current/storage/logs/laravel.log
นี้คือไฟล์ที่มีการตรวจสอบ Error และข้อมูลนี้ก็จะไปแสดงใน CloudWatch Log ของเราครับ (ในส่วนนี้ผมจะอธิบายในภายหลัง)
ต่อไปให้สลับ Terminal ไปยัง Server EC2 อีกตัว จะเห็นว่ายังไม่มีข้อมูล Error แสดงขึ้นมา
ทีนี้ให้กลับไปที่หน้าเว็บไซต์โปรเจ็กต์ที่ Error ของเราและ Reload 1-2 ครั้ง
แล้วกลับมาที่ Terminal จะเห็นว่ามี Error แสดงขึ้นมาแล้วครับ
ไปที่หน้า Service [CloudWatch > Log groups > /your_app_name/cloudwatchlog/laravel_log > i-your_instance_id]
จะเห็นว่ามีข้อมูล Error Log แสดงขึ้นมาแล้วครับ
Terminate Instance และตรวจสอบ CloudWatch Log
มาที่ Service [EC2 > Instance] แล้วทำการ Terminate instance ตัวไหนก็ได้สัก 1 ตัว
เช่นi-0d63fc42463547f0a
แล้วรอจนกว่า Instance state เป็นTerminate
เมื่อ Instance state เป็น Terminate แล้วให้กดปุ่ม Reload
จะเห็นว่ามี Instance ใหม่เพิ่มขึ้นมา 1 ตัว นั่นก็คือi-0b6f7576c18529905
ครับ
ทีนี้ให้มาที่หน้า Service [CloudWatch > Log groups > /your_app_name/cloudwatchlog/laravel_log]
จะเห็นว่า Log stream ของ Instance ID:i-0b6f7576c18529905
เพิ่มขึ้นมา ซึ่งยังไม่มีข้อมูล Error Log นะครับ (ถ้าต้องการดู Log ของ Instance ID ที่ Terminate ไปแล้ว คลิกเข้าไปที่ Instance ID นั้นได้เลยครับ)
ไปที่หน้าเว็บไซต์โปรเจกต์ที่ Error ของเรา แล้วทำการ Reload ประมาณ 2-3 ครั้งครับ
จากนั้นกลับมาที่หน้า Service [CloudWatch > Log groups > /your_app_name/cloudwatchlog/laravel_log] อีกครั้งแล้วทำการ Reload ครับ
ถ้า Last event time ในแถวของ Instance ID ตัวใหม่แสดงวันที่และเวลาขึ้นมาแล้ว ให้คลิกเข้าไปได้เลยครับ
จะเห็นว่ามีข้อมูล Error Log แสดงขึ้นมาแล้ว เพียงเท่านี้เราก็สามารถดูข้อมูล Log ใน Instance ของเราได้โดยไม่ต้องเข้าไปใน Linux และรันคำสั่งให้ยุ่งยากอีกต่อไปครับ
สรุป
ผมได้มีโอกาสใช้ CloudWatch Log แล้วทำให้ผมรู้สึกว่าเวลาจะดูข้อมูล Error, ข้อมูลการเชื่อมต่อ หรือประวัติการใช้งานต่างๆ ก็ไม่ต้องไปรันคำสั่งใน Server EC2 ทุกครั้งให้ยุ่งยาก และตั้งแต่ได้รู้จักกับ Service CloudWatch แล้วทำให้ผมได้เห็นถึงความสะดวกในการตรวจสอบข้อมูลที่เรียกว่า Log คือเราสามารถเข้าไปดูใน Service CloudWatch ได้เลยนั่นเอง
นอกจากนี้ต่อให้เราทำการ Terminate Instance ไปแล้วเราก็ยังสามารถดูประวัติการใช้งานย้อนหลังของ Instance นั้นใน CloudWatch Log ได้อีกด้วย
บทความที่เกี่ยวข้อง
- ทดลอง Deploy Laravel ด้วย Elastic Beanstalk และลองเชื่อมต่อกับ RDS
- การตั้งค่าที่จำเป็นเพื่อ Deploy Laravel ด้วย Elastic Beanstalk
- การสร้าง Role ใน IAM
- วิธี Copy การตั้งค่า Environment ใน Elastic Beanstalk และเริ่มต้นระบบ
- วิธีการใช้ ELB (ALB) ใน Elastic Beanstalk
- การสร้าง CloudWatch Log เพื่อใช้งานใน EC2
- วิธีการใช้ ELB (ALB) ใน Elastic Beanstalk